﻿using System;
using System.Collections.Generic;
using System.Linq;
using Atmk.WaterMeter.MIS.Commons.Interfaces.Repository;
using Atmk.WaterMeter.MIS.Datas;
using Atmk.WaterMeter.MIS.Entities;
using Atmk.WaterMeter.MIS.Entities.Common;
using Atmk.WaterMeter.MIS.Entities.Enums;
using Atmk.WaterMeter.MIS.Entities.Models;
using Atmk.WaterMeter.MIS.Services.DataAccess.Base;
using Microsoft.EntityFrameworkCore;

namespace Atmk.WaterMeter.MIS.Services.DataAccess
{
    public class DistrictRepository : BaseRepository, IDistrictRepository
    {
        /// <summary>
        /// 获取所有叶子节点
        /// </summary>
        /// <param name="staff"></param>
        /// <returns></returns>
        public List<District> GetLeafNodeDistricts(User user)
        {
           //获取所有根节点下属片区信息
            throw new NotImplementedException("该片区获取方式不实现");
        }

      
        /// <summary>
        /// 获取所有父节点片区
        /// </summary>
        /// <param name="staff"></param>
        /// <returns></returns>
        public List<District> GetFatherNodeDistricts(User user)
        {
            List<District> districts;
            if (user.Name == "admin")
            {
                //获取所有父区域集合
                districts = Context.District.AsNoTracking().Where(d => string.IsNullOrEmpty(d.Parent))
                    .ToList();
            }
            else
            {
                //获取片区集合
                var districtids = user.DistrictId.Split(',');
                //获取用户下父区域集合
                districts = Context.District.AsNoTracking()
                    .Where(d => districtids.Contains(d.Id.ToString()) && string.IsNullOrEmpty(d.Parent))
                    .ToList();
            }
            return districts;
        }

        /// <summary>
        /// 根据父节点获取叶子节点
        /// </summary>
        /// <param name="fatherNode"></param>
        /// <returns></returns>
        public List<District> GetLefNodeDistricts(List<District> fatherNode)
        {
            var result = Context.District.AsNoTracking()
                .Where(d => fatherNode.Select(f => f.Id.ToString()).Contains(d.Parent)).ToList();
            return result;
        }

        /// <summary>
        /// 根据id获取片区
        /// </summary>
        /// <param name="districtsId"></param>
        /// <returns></returns>
        public List<District> GetDistrictsById(params string[] districtsId)
        {
            var result = Context.District.AsNoTracking()
                .Where(d => districtsId.Contains(d.Id)).ToList();
            return result;
        }

        /// <summary>
        /// 根据项目ID获取主片区集合
        /// 这些片区代表各个小区
        /// </summary>
        /// <param name="projectId"></param>
        /// <returns></returns>
        public List<District> GetDistrictEntities(string projectId)
        {
            return Context.District.AsNoTracking()
                .Where(d => d.ProjectId == projectId && d.RecordState == (int)RecordStateEnum.Normal).ToList();
        }

        /// <summary>
        ///  获取叶子片区集合
        /// 这些片区直连了业主信息，没有被片区节点作为父片区，属于片区节点的叶子端
        /// </summary>
        /// <returns></returns>
        public List<District> GetLeafDistrictEntities()
        {
            return Context.District.AsNoTracking().Where(
                d => Context.Owner.AsNoTracking().Count(o =>
                         o.DistrictId == d.Id.ToString() && o.RecordState == (int)RecordStateEnum.Normal) > 0
                     && d.RecordState == (int)RecordStateEnum.Normal
            ).ToList();
        }

        /// <summary>
        ///  根据项目ID获取叶子片区集合
        /// 这些片区直连了业主信息，没有被片区节点作为父片区，属于片区节点的叶子端
        /// </summary>
        /// <param name="areaId"></param>
        /// <returns></returns>
        public List<District> GetLeafDistrictEntities(string areaId)
        {
            return GetLeafDistrictEntities().Where(
                d => d.ProjectId == areaId).ToList();
        }

        /// <summary>
        ///  根据项目ID和片区id获取下属获取叶子片区集合
        /// 这些片区直连了业主信息，没有被片区节点作为父片区，属于片区节点的叶子端
        /// </summary>
        /// <param name="areaId"></param>
        /// <param name="districtId"></param>
        /// <returns></returns>
        public List<District> GetLeafDistrictEntities(string areaId, string districtId)
        {
            return GetLeafDistrictEntities().Where(d =>
                d.Id.ToString() == districtId).ToList();
        }

        /// <summary>
        /// 根据项目和片区，获取叶子片区集合
        /// </summary>
        /// <param name="areaId"></param>
        /// <param name="districtId"></param>
        /// <returns></returns>
        public List<District> GetBaseDistrictEntities(string areaId, string districtId)
        {
            return !string.IsNullOrEmpty(districtId)
                ? GetLeafDistrictEntities(areaId, districtId)
                : string.IsNullOrEmpty(areaId)
                    ? GetLeafDistrictEntities().ToList()
                    : GetLeafDistrictEntities(areaId);
        }

        /// <inheritdoc />
        public List<DistrictSequences> GetDistrictSequencebyStaff(string staffId)
        {
            return Context.DistrictSequences.AsNoTracking().Where(d => d.StaffId == staffId).ToList();
        }

        /// <summary>
        /// 添加操作员下的片区排序
        /// </summary>
        /// <param name="DistrictSequences"></param>
        /// <returns></returns>
        public int AddDistrictSequence(DistrictSequences DistrictSequences)
        {
            Context.Add(DistrictSequences);
            return Context.SaveChanges();
        }

        /// <summary>
        /// 修改操作员下的片区排序
        /// </summary>
        /// <param name="DistrictSequences"></param>
        /// <returns></returns>
        public int UpdateDistrictSequence(DistrictSequences DistrictSequences)
        {
            using (var context = ContextBuilder.Build())
            {
                context.DistrictSequences.Attach(DistrictSequences);
                context.DistrictSequences.Update(DistrictSequences);
                return context.SaveChanges();
            }
        }

        /// <inheritdoc />
        public List<DistrictSequences> GetSameParentDistrictSequence(string staffId, Guid parentId)
        {
            var sameParentDistrict = Context.District.AsNoTracking().Where(d => d.Parent == parentId.ToId())
                .Select(d => d.Id);
            var sequence = Context.DistrictSequences.AsNoTracking()
                .Where(d => d.StaffId == staffId && sameParentDistrict.Contains(d.DistrictId)).ToList();
            return sequence;
        }

        public int Clear()
        {
            using (var context = ContextBuilder.Build())
            {
                var list = context.DistrictSequences;
                if(list.Any())
                    context.RemoveRange(list);
                return context.SaveChanges();
            }
        }
    }
}